﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Base;

namespace UtilZ.Dotnet.Ex.Communication.Net.Ftp
{
    /// <summary>
    /// ftp配置
    /// </summary>
    public class FtpConfig
    {
        /// <summary>
        /// 工作模式
        /// </summary>
        public FtpWorkMode WorkMode { get; set; } = FtpWorkMode.Mix;

        /// <summary>
        /// 控制命令连接监听EndPoint
        /// </summary>
        public IPEndPoint EndPoint { get; set; } = new IPEndPoint(IPAddress.Any, 21);

        /// <summary>
        /// tcp半连接队列长度
        /// </summary>
        public int Backlog { get; set; } = 100;

        /// <summary>
        /// 安全证书
        /// </summary>
        public X509Certificate Certificate { get; set; } = null;

        /// <summary>
        /// 主动模式(Port-Standard)端口,默认20.小于0由操作系统指定
        /// </summary>
        public ushort PortModePort { get; set; } = 20;

        /// <summary>
        /// 被动模式(Passive)端口范围最小值,需要大于1024,默认20000
        /// </summary>
        public ushort PassiveMinPort { get; set; } = 20000;

        /// <summary>
        /// 被动模式(Passive)端口范围最大值,需要大于最小值,默认40000
        /// </summary>
        public ushort PassiveMaxPort { get; set; } = 40000;

        /// <summary>
        /// 被动模式(Passive)忽略的端口列表
        /// </summary>
        public List<ushort> PassiveIgnorePortList { get; set; } = null;

        /// <summary>
        /// 被动模式等待ftp客户端连接建立超时时长
        /// </summary>
        public int PassiveMillisecondsTimeout { get; set; } = 30000;

        /// <summary>
        /// 编码
        /// </summary>
        public Encoding Encoding { get; set; } = EncodingEx.GetEncoding("gb2312");

        private Encoding _ebcdicEncoding = null;
        /// <summary>
        /// EBCDIC编码
        /// </summary>
        public Encoding EBCDICEncoding
        {
            get { return _ebcdicEncoding; }
            set { _ebcdicEncoding = value; }
        }

        private List<LocalPathItem> _rootPathItems = null;
        /// <summary>
        /// 根目录列表
        /// </summary>
        public List<LocalPathItem> RootPathItems
        {
            get { return _rootPathItems; }
            set { _rootPathItems = value; }
        }

        private bool _allowAnonymous = true;
        /// <summary>
        /// 允许匿名访问
        /// </summary>
        public bool AllowAnonymous
        {
            get { return _allowAnonymous; }
            set { _allowAnonymous = value; }
        }

        /// <summary>
        /// 有值为匿名登录用户,o 空或null表示禁止匿名登录
        /// </summary>
        public string Anonymous { get; set; } = "anonymous";

        /// <summary>
        /// 匿名用户登录密码
        /// </summary>
        public string AnonymousPassword { get; set; } = "IEUser@";

        /// <summary>
        /// 匿名用户访问策略
        /// </summary>
        public FtpAccessPolicy AnonymousAccessPolicy { get; set; } = FtpAccessPolicy.ReadAndWrite;

        private List<FtpUserInfo> _users = null;
        /// <summary>
        /// 用户列表
        /// </summary>
        public List<FtpUserInfo> Users
        {
            get { return _users; }
            set { _users = value; }
        }



        private FtpUserInfo _anonymousUserInfo = null;
        /// <summary>
        /// 匿名用户信息
        /// </summary>
        internal FtpUserInfo AnonymousUserInfo
        {
            get { return _anonymousUserInfo; }
        }


        /// <summary>
        /// 构造函数
        /// </summary>
        public FtpConfig()
        {
            try
            {
                this._ebcdicEncoding = EncodingEx.GetEncoding("IBM037");
            }
            catch (Exception ex)
            {
                ZLog.ZLoger.Warn(ex);

                this._ebcdicEncoding = Encoding.GetEncodings().Select(t =>
                {
                    return t.GetEncoding();
                }).FirstOrDefault(e =>
                {
                    return e.EncodingName.ToUpper().Contains("EBCDIC");
                });
            }
        }

        internal void MergePath()
        {
            if (this._allowAnonymous)
            {
                this._anonymousUserInfo = new FtpUserInfo()
                {
                    UserName = this.Anonymous,
                    Password = this.AnonymousPassword,
                    AccessPolicy = this.AnonymousAccessPolicy,
                };

                this._anonymousUserInfo.AppendPath(this._rootPathItems);
            }

            if (this._users == null || this._users.Count == 0)
            {
                if (!this._allowAnonymous)
                {
                    throw new ArgumentException("ftp已设置为不允许匿名访问,且没有指定可以访问的用户.");
                }
            }
            else
            {
                foreach (var user in this._users)
                {
                    user.AppendPath(this._rootPathItems);
                }
            }
        }

    }


}
